﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
using TEngine;
using Cysharp.Threading.Tasks;

namespace Launcher
{
    public class UIDefine
    {
        public static readonly string UILoadAlert = "UILoadAlert";
        public static readonly string UILimitRule = "UILimitRule";
        public static readonly string UIUserAgreement = "UIUserAgreement";
        public static readonly string UISplash = "UISplash";
        public static readonly string UIForceUpdate = "UIForceUpdate";

        public static readonly string UILoadUpdate = "UILoadUpdate";
    }

    public class PlayerPerfsDefind
    {
        public static readonly string AcceptUserAgreement = "AcceptUserAgreement";
    }

    /// <summary>
    /// 热更界面加载管理器。
    /// </summary>
    public static class LauncherMgr
    {
        private static Transform _uiRoot;
        private static readonly Dictionary<string, UIBase> _uiMap = new Dictionary<string, UIBase>();
        /// <summary>
        /// 正在加载的UI。（异步加载时使用）
        /// </summary>
        private static readonly HashSet<string> _pendingUIs = new HashSet<string>();

        /// <summary>
        /// 初始化根节点。
        /// </summary>
        public static void Initialize()
        {
            _uiRoot = GameObject.Find("UIRoot/UICanvas")?.transform;
            if (_uiRoot == null)
            {
                Debug.LogError("Failed to Find UIRoot. Please check the resource path");
                return;
            }

        }

        /// <summary>
        /// 隐藏ui对象。
        /// </summary>
        /// <param name="uiName">对应的ui的名称。</param>
        public static void Hide(string uiName)
        {
            if (string.IsNullOrEmpty(uiName))
            {
                return;
            }

            if (!_uiMap.TryGetValue(uiName, out var ui))
            {
                return;
            }

            ui.gameObject.SetActive(false);
            Object.DestroyImmediate(_uiMap[uiName].gameObject);
            _uiMap.Remove(uiName);
        }

        /// <summary>
        /// 获取显示的ui对象。
        /// </summary>
        /// <param name="uiName">对应的ui的名称。</param>
        /// <returns></returns>
        public static UIBase GetActiveUI(string uiName)
        {
            return _uiMap.GetValueOrDefault(uiName);
        }

        /// <summary>
        /// 隐藏所有热更相关UI。
        /// </summary>
        public static void HideAll()
        {
            foreach (var item in _uiMap)
            {
                if (item.Value && item.Value.gameObject)
                {
                    Object.Destroy(item.Value.gameObject);
                }
            }

            _uiMap.Clear();
        }

        #region 流程调用方法

        /// <summary>
        /// 显示提示框，目前最多支持三个按钮
        /// </summary>
        /// <param name="desc">描述</param>
        /// <param name="showtype">类型（MessageShowType）</param>
        /// <param name="onOk">点击事件</param>
        /// <param name="onCancel">取消事件</param>
        /// <param name="autoClose">自动关闭</param>
        public static void ShowLoadAlert(string desc, MessageShowType showtype = MessageShowType.OneButton,
            Action onOk = null,
            Action onCancel = null,
            bool autoClose = true
            )
        {
            LauncherMgr.ShowResourcesUI(UIDefine.UILoadAlert, desc);
            var ui = LauncherMgr.GetActiveUI(UIDefine.UILoadAlert) as UILoadAlert;
            if (ui == null)
            {
                return;
            }

            ui.OnOk = onOk;
            ui.OnCancel = onCancel;
            ui.Showtype = showtype;
            ui.AutoClose = autoClose;
            ui.OnEnter(desc);
        }

        public static void ShowUserAgreement(Action onOk = null, Action onCancel = null)
        {
            LauncherMgr.ShowResourcesUI(UIDefine.UIUserAgreement);
            var ui = LauncherMgr.GetActiveUI(UIDefine.UIUserAgreement) as UIUserAgreement;
            if (ui == null)
            {
                return;
            }
            ui.OnOk = onOk;
            ui.OnCancel = onCancel;
            ui.OnEnter(null);
        }

        public static void ShowLimitRule()
        {
            LauncherMgr.ShowResourcesUI(UIDefine.UILimitRule);
            var ui = LauncherMgr.GetActiveUI(UIDefine.UILimitRule) as UILimitRule;
            if (ui == null)
            {
                return;
            }
            ui.OnEnter(null);
        }

        public static void ShowSplash(Action onFinish)
        {
            LauncherMgr.ShowResourcesUI(UIDefine.UISplash);
            var ui = LauncherMgr.GetActiveUI(UIDefine.UISplash) as UISplash;
            if (ui == null)
            {
                return;
            }
            ui.OnVideoFinish = onFinish;
            ui.OnEnter(null);
        }


        public static void ShowLoadUpdate(string desc)
        {
            LauncherMgr.ShowStreamingUI(UIDefine.UILoadUpdate, desc).Forget();
            var ui = LauncherMgr.GetActiveUI(UIDefine.UILoadUpdate) as UILoadUpdate;
            if (ui == null)
            {
                return;
            }
            ui.OnEnter(desc);
        }

        /// <summary>
        /// 刷新UI版本号。
        /// </summary>
        /// <param name="appId">AppID。</param>
        /// <param name="resId">资源ID。</param>
        public static void RefreshVersion(string appId, string resId)
        {
            var ui = LauncherMgr.GetActiveUI(UIDefine.UILoadUpdate) as UILoadUpdate;
            if (ui == null)
            {
                return;
            }
            ui.OnRefreshVersion(appId, resId);
        }

        /// <summary>
        /// 更新UI文本。
        /// </summary>
        /// <param name="label">文本ID。</param>
        public static void UpdateUILabel(string label)
        {
            var ui = LauncherMgr.GetActiveUI(UIDefine.UILoadUpdate) as UILoadUpdate;
            if (ui == null)
            {
                return;
            }

            ui.OnEnter(label);
        }

        /// <summary>
        /// 更新UI进度。
        /// </summary>
        /// <param name="progress">当前进度。</param>
        public static void UpdateUIProgress(float progress)
        {
            var ui = LauncherMgr.GetActiveUI(UIDefine.UILoadUpdate) as UILoadUpdate;
            if (ui == null)
            {
                return;
            }
            ui.OnUpdateUIProgress(progress);
        }

        #endregion

        #region 内部show ui方法

        /// <summary>
        /// 设置UI组件排版
        /// </summary>
        /// <param name="ui"></param>
        private static void SetupUIObject(GameObject ui)
        {
            if (ui == null) return;

            ui.transform.SetParent(_uiRoot.transform);
            ui.transform.localScale = Vector3.one;
            ui.transform.localPosition = Vector3.zero;

            RectTransform rect = ui.GetComponent<RectTransform>();
            if (rect != null)
                rect.sizeDelta = Vector2.zero;
            else
                Debug.LogError("UI对象缺少RectTransform组件");
        }

        private static bool TryAddUIComponent(string uiInfo, GameObject uiInstance)
        {
            UIBase component = uiInstance.GetComponent<UIBase>();
            if (component != null)
            {
                _uiMap.Add(uiInfo, component);
                return true;
            }

            Debug.LogError($"UI预制体 {uiInfo} 缺少UIBase组件");
            Object.Destroy(uiInstance);
            return false;
        }

        private static void ActivateUI(string uiInfo, object param)
        {
            if (_uiMap.TryGetValue(uiInfo, out UIBase component))
            {
                component.gameObject.SetActive(true);
                component.OnEnter(param);
            }
        }

        /// <summary>
        /// 显示Resources中的UI
        /// </summary>
        private static void ShowResourcesUI(string uiInfo, object param = null)
        {
            if (string.IsNullOrEmpty(uiInfo)) return;

            if (!_uiMap.ContainsKey(uiInfo))
            {
                GameObject obj = Resources.Load<GameObject>($"AssetLoad/{uiInfo}");
                if (obj != null)
                {
                    GameObject ui = Object.Instantiate(obj);
                    SetupUIObject(ui);

                    if (TryAddUIComponent(uiInfo, ui))
                    {
                        ActivateUI(uiInfo, param);
                    }
                }
                else
                {
                    Debug.LogError($"ShowResourcesUI资源加载失败：{uiInfo}");
                }
            }

            ActivateUI(uiInfo, param);
        }

        /// <summary>
        /// 显示StreamingAssets中的UI
        /// </summary>
        /// <param name="uiInfo"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        private static async UniTask ShowStreamingUI(string uiInfo, object param = null)
        {
            if (string.IsNullOrEmpty(uiInfo)) return;

            // 等待正在进行的加载完成
            while (_pendingUIs.Contains(uiInfo))
            {
                await UniTask.Yield();
            }

            try
            {
                // 如果已经存在缓存，直接激活
                if (_uiMap.TryGetValue(uiInfo, out UIBase cachedComponent))
                {
                    cachedComponent.gameObject.SetActive(true);
                    cachedComponent.OnEnter(param);
                    return;
                }

                // 标记为正在加载
                _pendingUIs.Add(uiInfo);

                IResourceModule _resourceModule = ModuleSystem.GetModule<IResourceModule>();
                GameObject obj = await _resourceModule.LoadAssetAsync<GameObject>(UIDefine.UILoadUpdate, default);

                // 二次检查：加载完成后再次确认是否需要实例化
                if (_uiMap.ContainsKey(uiInfo))
                {
                    Object.Destroy(obj);  // 清理不需要的资源
                    _uiMap[uiInfo].gameObject.SetActive(true);
                    _uiMap[uiInfo].OnEnter(param);
                    return;
                }

                if (obj != null)
                {
                    GameObject ui = Object.Instantiate(obj);
                    SetupUIObject(ui);

                    if (TryAddUIComponent(uiInfo, ui))
                    {
                        ActivateUI(uiInfo, param);
                    }
                }
                else
                {
                    Debug.LogError($"ShowResourcesUI资源加载失败：{uiInfo}");
                }
            }
            finally
            {
                _pendingUIs.Remove(uiInfo);  // 确保始终移除加载标记
            }
        }
        #endregion
    }
}